import java.awt.event.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 * Server for itunes related things.
 */
class ITunesServer extends LocalServer {

  protected boolean showIP() {return true;}

  private final ITunesController itunes = new ITunesController();
  { itunes.setDebug(true); }
  private final OS os = new OS();
  private final MusicLibrary lib = new MusicLibrary(getITunesMusicLibrary());

  private final static String SEP = "\t";

  /** Returns the artists */
  private class GetArtistsHandler extends AbstractListHandler {

    public String handle(Map<String,String> args) {
      lib.fill();
      return stringList(lib);
    }

    GetArtistsHandler() {
      super("GetArtists");
    }
  }

  /** Returns a list of the artist and albums. */
  private class GetAlbumsHandler extends AbstractListHandler {

    public String handle(Map<String,String> args) {
      lib.fill();
      Artist v = lib.get(get(args,"name"));
      return v.getName() + SEP + stringList(v);
    }

    GetAlbumsHandler() {
      super("GetAlbums");
    }
  }

  /** Returns the artist, album, and tracks. */
  private class GetTracksHandler extends AbstractListHandler {

    public String handle(Map<String,String> args) {
      lib.fill();
      Artist a = lib.get(get(args,"artist"));
      Album v = a.get(get(args,"name"));
      return a.getName() + SEP + v.getName() + SEP + stringList(v);
    }

    GetTracksHandler() {
      super("GetTracks");
    }
  }

  /** Shows a pop up of the messsage. */
  private class EchoHandler extends AbstractHandler {

    public String handle(Map<String,String> args) {
      return "ok";
    }

    EchoHandler() {
      super("Echo");
    }
  }

  /** Tell itunes 'Back' */
  private class BackHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      itunes.back();
      note("itunes back");
      return "ok";
    }
    BackHandler() {
      super("Back");
    }
  }

  /** Tell itunes 'Stop' */
  private class StopHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      itunes.stop();
      note("itunes stop");
      return "ok";
    }
    StopHandler() {
      super("Stop");
    }
  }

  /** Tell itunes 'Play' */
  private class PlayHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      itunes.play();
      note("itunes play");
      return "ok";
    }
    PlayHandler() {
      super("Play");
    }
  }

  /** Tell itunes 'Play' a track with id id */
  private class PlayTrackHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      String name = getArg(args,"name");
      itunes.playTrack(name);
      note("itunes playTrack " + name);
      return "ok";
    }
    PlayTrackHandler() {
      super("PlayTrack");
    }
  }

  /** Tell itunes set the volume different. */
  private class SetVolumeHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      String volume = getArg(args,"volume");
      itunes.setVolume(Integer.parseInt(volume));
      note("itunes set volume " + volume);
      return "ok";
    }
    SetVolumeHandler() {
      super("SetVolume");
    }
  }

  /** Gets the status */
  private class GetStatusHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      return itunes.getStatus();
    }
    GetStatusHandler() {
      super("GetStatus");
    }
  }

  /** Tell itunes 'Next' */
  private class NextHandler extends AbstractHandler {
    public String handle(Map<String,String> args) {
      itunes.next();
      note("itunes next");
      return "ok";
    }
    NextHandler() {
      super("Next");
    }
  }


  /** Handler that can create a String from a list. */
  private abstract class AbstractListHandler extends AbstractHandler {

    protected final String stringList(HasNameList v) {
      StringBuffer s = new StringBuffer();
      for (Object o : v.getValues()) {
        HasName a = (HasName)o;
        s.append(a.getName()).append(SEP);
      }
      s.trimToSize();
      return s.toString();
    }

    AbstractListHandler(String s) {
      super(s);
    }
  }

  private File getITunesMusicLibrary() {
    return new File(getITunesHome(), "iTunes Music Library.xml");
  }

  private File getITunesHome() {
    return new File(os.getMusicHome(), "iTunes");
  }

  Handler[] getHandlers() {
    return new Handler[] {
      new GetArtistsHandler(),
      new GetAlbumsHandler(),
      new GetTracksHandler(),
      new BackHandler(),
      new StopHandler(),
      new PlayHandler(),
      new PlayTrackHandler(),
      new NextHandler(),
      new EchoHandler(),
      new SetVolumeHandler(),
      new GetStatusHandler(),
    };
  }

  public static void main(String args[]) {
    new ITunesServer().realMain(args);
  }
  
}
